/**
 * @author Paulo Faria Reis
 * @created 15 Mar 2012
 *
 */
package networkoperations;

import controller.DataStore;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.MulticastSocket;
import fileoperations.FileSender;

/**
 * @author Paulo Faria Reis
 */
public class MulticastListener implements Runnable{
	DataStore dataStorage;
	//	String request;		// Message received by the server.
	//	byte[] msgOut;		// Message to send in the packet.
	byte[] msgIn = new byte[1024];		// Received message.
	String controlPayload;
	MulticastSocket controlSocket = null;
	private volatile boolean dontStop = true;

	/**
	 *  Constructor.
	 */
	public MulticastListener(DataStore dataStor) {
		dataStorage = dataStor;
	}

	/**
	 *  Listens to the multicast control channel.
	 *  Creates a new Replier thread for each SEARCH received.
	 *  Creates a new Sender thread for each GET that it has a chunk.
	 */
	@Override
	public void run(){
		DatagramPacket controlPack = new DatagramPacket(msgIn, msgIn.length);

		// Creates socket and join the group.
		try {
			controlSocket = new MulticastSocket(dataStorage.getControlPort());
			controlSocket.joinGroup(dataStorage.getMcAddress());
		} catch (IOException e1) {
			if(dataStorage.debug()) {
				System.out.println("I/O Invalido while trying to create socket and join group!");
				e1.printStackTrace();
			}
		}

		// Keeps listening for packets and process them.
		while(dataStorage.keepWorking() || dontStop) {
			if(dataStorage.debug()) System.out.println("Ready to receive messages...");

			try {
				controlSocket.receive(controlPack);
			}
			catch (IOException e) {
				if(dataStorage.debug()) {
					System.out.println("I/O Invalido getting datagram from socket!");
					e.printStackTrace();
				}
			}
			controlPayload = new String(controlPack.getData(), 0, controlPack.getLength());
			if(dataStorage.debug()){
				System.out.println("Sender: " + controlPack.getAddress().toString() + ":" + controlPack.getPort());
				System.out.println("Size: " + controlPack.getLength());
				System.out.println("Message: " + controlPayload);
			}

			// For each request for a file search launch a thread to answer.
			if(controlPayload.startsWith("SEARCH"))
			{
				Replier newSearch = new Replier();
				newSearch.start();
			}
			// For each file requested start a thread to send (chunks of) the file.
			else if(controlPayload.startsWith("GET")){
				FileSender fileS = new FileSender(controlPayload);
				fileS.start();		
			}
			else if(controlPayload.startsWith("FOUND")){
				// TODO code to register answer to files searched by the user.
				System.out.println("FOUND message detected by MulticastListener.");
			}
		}	
		try {
			controlSocket.leaveGroup(dataStorage.getMcAddress());
		} catch (IOException e) {
			System.out.println("I/O Invalido leaving group!");
			e.printStackTrace();
		}
		controlSocket.close();
	}	

	/**
	 *  Stops the thread.
	 */
	public void stopWork() {
		dontStop = false;
	}
}
